#include "misc_system.h"

#include "service/include/swei_package.h"
#include "service/include/swei_location.h"

#include "global.h"
#include "task_misc.h"
#include "misc_log.h"


#include "service/include/swei_config.h"
#include "service/include/swei_login.h"
#include "service/include/swei_status.h"


/**
 * @brief 返回激活状态 1 - 激活 0 - 未激活
 * @return active_state_e 
 */
active_state_e misc_get_active_state(void)
{
    return swei_is_active() ? ACTIVE : INACTIVE;
}


#include "comm/co_heartbeat.h"
/**
 * @brief 返回工作模式
 * @return work_mode_e WORK_MODE_NORMAL - 正常模式; WORK_MODE_SLEEP - 休眠模式
 */
work_mode_e misc_get_work_mode(void)
{
    return is_ebike_mcu_off() ? WORK_MODE_SLEEP : WORK_MODE_NORMAL;
}


#include "service/include/swei_config.h"
#include "service/include/swei_login.h"
#include "service/include/swei_location.h"


#include "common/utils/utils_timer.h"
extern utils_time_t gps_upload_timer;
extern utils_time_t lbs_upload_timer;
extern utils_time_t wifi_upload_timer;
extern utils_time_t rsrp_upload_timer;
extern utils_time_t batt_upload_timer;
extern utils_time_t can_info_type1_rpt_timer;
extern utils_time_t can_info_type2_rpt_timer;

/* 以下函数获取发送剩余时间 */
unsigned int get_gps_report_next_send(void)
{
    return utils_time_left(&gps_upload_timer);;
}

unsigned int get_lbs_report_next_send(void)
{
    return utils_time_left(&lbs_upload_timer);;
}
unsigned int get_wifi_report_next_send(void)
{
    return utils_time_left(&wifi_upload_timer);;
}

unsigned int get_rsrp_report_next_send(void)
{
    return utils_time_left(&rsrp_upload_timer);
}

unsigned int get_can_info_type1_report_next_send(void)
{
    return utils_time_left(&can_info_type1_rpt_timer);
}

unsigned int get_can_info_type2_report_next_send(void)
{
    return utils_time_left(&can_info_type2_rpt_timer);
}

unsigned int get_batt_report_next_send(void)
{
    return utils_time_left(&batt_upload_timer);
}


/* 非激活上报, 上电计时两分钟完成上报 */
void rpt_inactive(void) 
{
    static uint8_t upload_lbs = true;
    static uint8_t upload_gps = true;
    static uint8_t upload_wifi = true;
    static utils_time_t timer_2min = {0};
    static uint8_t rpt_timer_fresh = 0;

    if (INACTIVE != misc_get_active_state()) { 
        rpt_timer_fresh = 1;
        upload_gps = true;
        upload_lbs = true;
        upload_wifi = true;
        return;
    } 

    if (rpt_timer_fresh) {
        rpt_timer_fresh = 0;
        utils_time_countdown_ms(&gps_upload_timer, 0);
        utils_time_countdown_ms(&lbs_upload_timer, 0);
        utils_time_countdown_ms(&wifi_upload_timer, 0);
        utils_time_countdown_ms(&timer_2min, 2 * 60 * 1000);
    }

    if ((!upload_gps) && (!upload_lbs) && (!upload_wifi))
        return;

    if (upload_gps && !utils_time_is_expired(&timer_2min))
    {
        if (0 == swei_location_push_gps())
        {
            upload_gps = false;
        }
    }

    if (upload_lbs && !utils_time_is_expired(&timer_2min))
    {
        if (0 == swei_location_push_lbs())
        {
            upload_lbs = false;
        }
    }

#if SUPPORT_FOR_WIFI_UPLOAD   
    if (upload_wifi && !utils_time_is_expired(&timer_2min))
    {
        if (0 == swei_location_push_wifi())
        {
            upload_wifi = false;
        }
    }
#endif    
}

uint8_t corner_rpt_enable = 0;

/**
 * @brief 激活且仪表开机状态下周期上报
 */
void rpt_active_normal(void)
{
    static uint8_t rpt_timer_fresh = 0;

    if (WORK_MODE_NORMAL!= misc_get_work_mode()) {  /* 模式切换保证能够数据立即上报 */
        // 重置计时器，以保证模式切换时能立即上报数据
        rpt_timer_fresh = 1;
        return;
    } 

    if (rpt_timer_fresh) {
        rpt_timer_fresh = 0;
        utils_time_countdown_ms(&can_info_type1_rpt_timer, 0);
        utils_time_countdown_ms(&can_info_type2_rpt_timer, 0);
    }

    if (corner_rpt_enable) {
        corner_rpt_enable = 0;

        swei_location_push_corner_gps();      // 拐弯上报
    }

    swei_status_push_caninfo_type1();  
    swei_status_push_caninfo_type2(); 
}


/**
 * @brief 激活且仪表关机状态下周期上报
 */
void rpt_active_lowpower(void)
{
    static uint8_t rpt_timer_fresh = 0;
    if (WORK_MODE_SLEEP != misc_get_work_mode()) {
        rpt_timer_fresh = 1;
        return;
    } 

    if (rpt_timer_fresh) {
        rpt_timer_fresh = 0;
        utils_time_countdown_ms(&batt_upload_timer, 0);
    }
    
    swei_status_push_libatt();      // 小电池电量上报
}

/**
 * @brief 激活上报
 */
void rpt_active(void)
{
    static uint8_t rpt_timer_fresh = 0;
    if (ACTIVE != misc_get_active_state()) {    /** 非激活状态下更新定时器 */
        // 重置计时器，以保证模式切换时能立即上报数据
        rpt_timer_fresh = 1;
        return;
    }

    if (rpt_timer_fresh) {
        rpt_timer_fresh = 0;
        utils_time_countdown_ms(&gps_upload_timer, 0);
        utils_time_countdown_ms(&lbs_upload_timer, 0);
        utils_time_countdown_ms(&wifi_upload_timer, 0);
        utils_time_countdown_ms(&rsrp_upload_timer, 0);
    }

    /* 以下数据定期上报 */
    swei_location_push_gps();
    swei_location_push_lbs();
#if SUPPORT_FOR_WIFI_UPLOAD    
    swei_location_push_wifi();
#endif    
    swei_status_push_rsrp();        // 信号强度上传

    // 1. 激活工作模式上报
    rpt_active_normal();
    // 2. 激活休眠模式上报
    rpt_active_lowpower();
}


/**
 * @brief 触发GPS上报
 */
void gps_report_trigger(void)
{
    utils_time_countdown_ms(&gps_upload_timer, 0);
}

/**
 * @brief 触发GPS拐点上报
 */
void corner_report_trigger(void)
{   
    corner_rpt_enable = 1;
}

/**
 * @brief 触发LBS上报
 */
void lbs_report_trigger(void)
{
    utils_time_countdown_ms(&lbs_upload_timer, 0);
}

/**
 * @brief 定时report接口
 */
void misc_fix_report_process(void)
{
    // 1. 非激活上报
    rpt_inactive();
    
    // 2. 激活上报
    rpt_active();
}


#include "comm/co_heartbeat.h"
#include "service/include/port/swei_wrapper.h"

/**
 * @brief 开关机事件报文，开机0x5001,关机0x5002，未激活2分钟超时不发送以下数据
 */
static void misc_comcu_event_handler(void)
{
    static uint8_t last_status = false;   /* 默认仪表关机状态 */
    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    
    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    if (last_status != is_ebike_mcu_off()) {    /* 仪表开关机状态变化 */
        last_status = is_ebike_mcu_off();

        switch (last_status) {
            case false: { /* 仪表开机，触发开机事件 */
                /* 非激活2分钟后超时不上报开关机事件 */
                if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
                    break;
                }
                swei_status_lock();
                // 产生新的workid
                swei_gen_workid();
                /* 上报 0x1001 */
                swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_INFO, 0);

                if (is_backup_batt_insert()) {
                    /* 上报 0x1009 */
                    swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_BACK_INFO, 1);
                    /* 上报 0x100E */
                    swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_BACK_CYCLE_TIMES, 1);
                }

                /* 上报 0x2003 */
                swei_status_event_update(CAN_UPLOAD_TAG_ID_ELEC_CON_VER, 1);
                /* 上报 0x3003 */
                swei_status_event_update(CAN_UPLOAD_TAG_ID_BIKE_STATE, 0);
                /* 上报 0x5001 */
                swei_status_event_update(CAN_UPLOAD_DEV_INFO, 0);
                /* 上报 0x5002 */
                swei_status_event_update(CAN_UPLOAD_STATUS_INFO, 1);
                swei_status_unlock();
            }break;
            case true: { /* 仪表关机，触发关机事件 */
                swei_status_lock();
                /* 上报 0x100E */
                swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_BACK_CYCLE_TIMES, 1);
                /* 上报 0x2003 */
                swei_status_event_update(CAN_UPLOAD_TAG_ID_ELEC_CON_VER, 1);
                /* 0x5002 */
                swei_status_event_update(CAN_UPLOAD_STATUS_INFO, 0);
                swei_status_unlock();
            }break;
        }
    }
}

/**
 * @brief 电机挡位变化报文（0x2002）
 */
static void misc_econ_event_handler(void)
{
    static int8_t last_status = -1;   /* 默认电机挡位为无效 */
    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    
    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    if (last_status != get_ebike_pwr_lvl()) {    /* 电机挡位变化 */
        last_status = get_ebike_pwr_lvl();

        /* 挡位无效，不处理 */
        if (last_status < 0)
            return;

        /* 非激活2分钟后超时不上报开关机事件 */
        if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
            return;
        }

        swei_status_event_update(CAN_UPLOAD_TAG_ID_ELEC_CON_RUNNING, 0);
    }
}


/**
 * @brief 车辆状态变化报文（0x3003）
 */
static void misc_ebike_event_handler(void)
{
    //static int8_t last_status = false;          /* 默认车辆状态为不骑行 */
    static uint8_t last_elock_status = 0xFF;    /* 默认电子锁状态为无效状态 */ 
    static uint8_t last_charger_status = 0xFF;  /* 默认充电器连接状态为无效状态 */
    static uint8_t last_light_status = 0xFF;    /* 默认尾灯状态为无效状态 */


    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    
    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    if (last_elock_status != get_elock_status()\
        || last_charger_status != is_charger_inserted()\
        || last_light_status != is_rear_light_on()) {    /* 车辆状态变化 */
        last_elock_status = get_elock_status();
        last_charger_status = is_charger_inserted();
        last_light_status = is_rear_light_on();

        /* 非激活2分钟后超时不上报车辆状态变化事件 */
        if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
            return;
        }

        swei_status_event_update(CAN_UPLOAD_TAG_ID_BIKE_STATE, 0);
    }
}


/**
 * @brief 仪表上下电事件报文，主电池充电循环次数(0x1006，canID=0x05FF3302)报文
 */
static void misc_power_event_handler(void)
{
    static uint8_t last_status = false;   /* 默认仪表上下电状态 */
    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    
    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    if (last_status != is_ebike_mcu_off()) {    /* 仪表上下电状态变化 */
        last_status = is_ebike_mcu_off();

        /* 非激活2分钟后超时不上报开关机事件 */
        if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
            return;
        }        

        swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_CYCLE_TIMES, 0);
    }
}


co_fault_code_t fault_code_tbl[FAULT_NUM] = {0};

/**
 * @brief 查询仪表状态码是否有变化
 * 
 * @param type 
 * @param fault_code 
 * @return true 状态码有变化
 * @return false 状态码没有变化
 */
static bool  search_fault_code(int type, co_fault_code_t* fault_code)
{
    switch (type)
    {
    case FAULT_ECON:
        econ_fault_info_get((uint8_t *)fault_code, sizeof(co_fault_code_t));

        if (0 != memcmp(fault_code, &fault_code_tbl[type], sizeof(co_fault_code_t))) {
            memcpy(&fault_code_tbl[type], fault_code, sizeof(co_fault_code_t));
            return true;
        }
        else 
            return false;
        break;

    case FAULT_BATT:
        batt_fault_info_get((uint8_t *)fault_code, sizeof(co_fault_code_t));

        if (0 != memcmp(fault_code, &fault_code_tbl[type], sizeof(co_fault_code_t))) {
            memcpy(&fault_code_tbl[type], fault_code, sizeof(co_fault_code_t));
            return true;
        }
        else 
            return false;
        break;

    case FAULT_BACKUP_BATT:
        backup_batt_fault_info_get((uint8_t *)fault_code, sizeof(co_fault_code_t));

        if (0 != memcmp(fault_code, &fault_code_tbl[type], sizeof(co_fault_code_t))) {
            memcpy(&fault_code_tbl[type], fault_code, sizeof(co_fault_code_t));
            return true;
        }
        else 
            return false;
        break;

    // case FAULT_CHARGER:
    //     charger_fault_info_get((uint8_t *)fault_code, sizeof(co_fault_code_t));

    //     if (0 != memcmp(fault_code, &fault_code_tbl[type], sizeof(co_fault_code_t))) {
    //         memcpy(&fault_code_tbl[type], fault_code, sizeof(co_fault_code_t));
    //         return true;
    //     }
    //     else 
    //         return false;
    //     break;

    // case FAULT_ELOCK:
    //     elock_fault_info_get((uint8_t *)fault_code, sizeof(co_fault_code_t));

    //     if (0 != memcmp(fault_code, &fault_code_tbl[type], sizeof(co_fault_code_t))) {
    //         memcpy(&fault_code_tbl[type], fault_code, sizeof(co_fault_code_t));
    //         return true;
    //     }
    //     else 
    //         return false;
    //     break;   
    
    default:
            return false;
        break;
    }
}


/**
 * @brief 仪表故障码事件报文，故障码（0x4001）
 */
static void misc_fault_code_event_handler(void)
{
    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    static co_fault_code_t fault_code[FAULT_NUM] = {0};
    
    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    /* 非激活2分钟后超时不上报事件 */
    if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
        return;
    }    

    /* 只有检测到有新的故障码产生 */
    for (int i = 0; i < FAULT_NUM; i++) {
        if (search_fault_code(i, &fault_code[i])) {     
            swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_WARNING_CODE, i);
        }
    }
}


#if 0
/**
 * @brief 备用电池充电状态信息报文（0x4001）。开始充电和停止充电时上报
 */
static void misc_backup_charging_event_handler(void)
{
    static uint8_t rpt_timer_fresh = 1;
    static utils_time_t rpt_timer = {0};
    /* 初始充电状态为未在位 */
    static int8_t last_status = -1;

    if (rpt_timer_fresh && INACTIVE == misc_get_active_state()) {
        utils_time_countdown_ms(&rpt_timer, 2 * 60 * 1000);
        rpt_timer_fresh = 0;
    }  else if(ACTIVE == misc_get_active_state()) {
        rpt_timer_fresh = 1;
    }

    if (last_status != get_backup_batt_charging_status()) {    /* 充电状态变化 */
        /* 备用电池充电状态为未在位 */
        if (-1 == get_backup_batt_charging_status())
            return;

        last_status = get_backup_batt_charging_status();

        /* 非激活2分钟后超时不上报充电状态变化事件 */
        if (INACTIVE == misc_get_active_state() && utils_time_is_expired(&rpt_timer)) {
            return;
        }

        /* 上报备电充电状态信息（0x100C） */
        swei_status_event_update(CAN_UPLOAD_TAG_ID_BMS_BACK_CHARGE_INFO, 0);
    }

}
#endif


/**
 * @brief 系统事件处理接口,非激活状态下，开机2分钟后不上报数据
 */
void misc_system_event_process(void)
{
    misc_comcu_event_handler();
    misc_ebike_event_handler();
    misc_fault_code_event_handler();
    misc_power_event_handler();
    misc_econ_event_handler();
    //misc_backup_charging_event_handler();
    // misc_service_event_handler();
}


/**
 * @brief 理解上报GPS
 */
void swei_location_push_gps_fast(void)
{
    gps_report_trigger();
}

/**
 * @brief 立即上报LBS
 */
void swei_location_push_lbs_fast(void)
{
    lbs_report_trigger();
}